package cn.com.lyb;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;

import static java.nio.file.StandardWatchEventKinds.*;

/**
 * 监控类
 */
public class DirectoryWatcherService {
    private final WatchService watchService;
    private final Map<WatchKey, Path> watchKeys;

    public DirectoryWatcherService(Path dir) throws IOException {
        this.watchService = FileSystems.getDefault().newWatchService();
        this.watchKeys = new HashMap<>();
        registerAll(dir);
    }

    /**
     * 注册指定目录及其所有子目录的监控
     */
    private void registerAll(final Path start) throws IOException {
        Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                register(dir);
                return FileVisitResult.CONTINUE;
            }
        });
    }

    /**
     * 注册目录监控
     */
    private void register(Path dir) throws IOException {
        WatchKey key = dir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
        watchKeys.put(key, dir);
    }

    /**
     * 监控目录变化
     */
    public void startWatching() {
        System.out.println("我要开始工作了========");

        while (true) {
            WatchKey key;
            try {
                key = watchService.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
                return;
            }

            Path dir = watchKeys.get(key);
            if (dir == null) {
                continue;
            }

            for (WatchEvent<?> event : key.pollEvents()) {
                WatchEvent.Kind<?> kind = event.kind();
                Path name = (Path) event.context();
                Path child = dir.resolve(name);
                System.out.println("0000000000000000000000"+ kind);
                if (kind == ENTRY_CREATE) {
                    if (Files.isDirectory(child)) {
                        try {
                            registerAll(child);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    handleFileCreate(child);
                } else if (kind == ENTRY_MODIFY) {
                    handleFileModify(child);
                } else if (kind == ENTRY_DELETE) {
                    handleFileDelete(child);
                }
            }

            boolean valid = key.reset();
            if (!valid) {
                watchKeys.remove(key);
                if (watchKeys.isEmpty()) {
                    break;
                }
            }
        }
    }

    private void handleFileCreate(Path filePath) {
        if (filePath.getFileName().toString().startsWith("~$") || filePath.getFileName().toString().endsWith(".tmp")) {
            //System.out.println("忽略临时文件: ----------------" + filePath);
            return;
        }

        System.out.println("每次只需要关心这个东西，备份文件=（删除旧的，新增新的） ++++++++" + filePath  + "文件大小" +filePath.toFile().length());

    }

    private void handleFileModify(Path filePath) {
        if (filePath.getFileName().toString().startsWith("~$") || filePath.getFileName().toString().endsWith(".tmp")) {
            //System.out.println("忽略临时文件: ----------------" + filePath);
            return;
        }
        File file = filePath.toFile();
        if(file.isDirectory()){
            System.out.println("文件夹修改了 ++++++++:" + filePath);
        }else {
            System.out.println("文件修改了 需要关心 ++++++++:" + filePath);
        }

    }

    private void handleFileDelete(Path filePath) {
        if (filePath.getFileName().toString().startsWith("~$") || filePath.getFileName().toString().endsWith(".tmp")) {
            //System.out.println("忽略临时文件: ----------------" + filePath);
            return;
        }
        System.out.println("删除文件或目录  文件名称或者路径，不用关心---------" + filePath);

    }

    public static void main(String[] args) {
        try {
            Path dir = Paths.get("D:\\opt\\yeexun\\11");
            DirectoryWatcherService watcher = new DirectoryWatcherService(dir);
            watcher.startWatching();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
